<template>
  <div class="assignment">
    <div class="assignment-header">
      <div class="title">分配数字人</div>
      <div class="stats">
        已分配 {{ assignedCount }}/{{ totalCount }}
      </div>
    </div>

    <!-- 添加模型源选择器 -->
    <div class="model-source-selector">
      <div
        class="selector-option"
        :class="{ active: modelSource === 'local' }"
        @click="action.switchModelSource('local')"
      >
        本地模型
      </div>
      <div
        class="selector-option"
        :class="{ active: modelSource === 'common' }"
        @click="action.switchModelSource('common')"
      >
        公共库模型
      </div>
    </div>

    <!-- 批量分配区域 - 修改为使用按钮打开模态窗口 -->
    <div class="batch-assignment">
      <div class="batch-assignment-title">批量分配</div>
      <div class="batch-assignment-control">
        <!-- 替换原有的t-select为按钮，点击后打开模态窗口 -->
        <div class="model-selector-button-container">
          <t-button
            class="model-selector-button"
            @click="action.openModelSelectorModal"
          >
            {{ state.batchSelectedModel ? getSelectedModelName() : '选择要批量分配的数字人' }}
          </t-button>
          <t-button v-if="state.batchSelectedModel"
                    theme="default"
                    variant="text"
                    size="small"
                    @click="action.clearSelectedModel"
          >
            清除
          </t-button>
        </div>

        <t-button
          theme="primary"
          @click="action.batchAssignModel"
          :disabled="!state.batchSelectedModel"
        >
          批量分配
        </t-button>
      </div>

      <!-- 批量分配选项 -->
      <div class="batch-options">
        <t-checkbox v-model="state.includeAssigned"><span>包含已分配的内容项</span></t-checkbox>
        <t-tooltip content="勾选后，将重新分配所有内容项，包括已分配给其他数字人的内容">
          <InfoCircleIcon class="info-icon" />
        </t-tooltip>
      </div>
    </div>

    <div class="assignment-tabs">
      <t-tabs v-model="state.activeTab">
        <t-tab-panel value="contentView" label="内容视图">
          <div class="content-view">
            <div
              v-for="item in getCurrentPageContentItems()"
              :key="item.id"
              class="content-item"
            >
              <div class="content-details">
                <div class="content-type">
                  <span class="type-badge audio">音频</span>
                </div>
                <div class="content-name">{{ item.name || '未命名' }}</div>
                <div class="content-preview">
                  <div class="audio-preview">
                    <t-button class="preview-btn" size="small" @click="action.previewAudio(item)">试听</t-button>
                  </div>
                </div>
              </div>

              <div class="content-assignment">
                <div class="assignment-label">分配数字人：</div>
                <!-- 内容视图中的单个内容项分配也使用改进的选择器 -->
                <div class="single-model-selector">
                  <t-button
                    class="model-selector-button"
                    @click="(event) => action.openModelSelectorModal(event, item.id)"
                  >
                    {{ getAssignedModelName(item.id) || '选择数字人' }}
                  </t-button>
                  <t-button v-if="getAssignedModelId(item.id)"
                            theme="default"
                            variant="text"
                            size="small"
                            @click="() => action.assignModel(item.id, null)"
                  >
                    清除
                  </t-button>
                </div>
              </div>
            </div>
          </div>
          <!-- 有内容无模型时显示 -->
          <div v-if="videoData.contentItems.length === 0" class="no-models">
            <div class="loading-content">
              <div class="loading-text">暂无内容</div>
            </div>
          </div>
          <!-- 添加内容视图的分页控件 -->
          <div class="pagination-container" v-if="videoData.contentItems.length > 0">
            <t-pagination
              v-model="state.contentPagination.current"
              v-model:pageSize="state.contentPagination.pageSize"
              :total="videoData.contentItems.length"
              :page-size-options="[5, 10, 20, 50]"
              @change="action.onContentPageChange"
              @page-size-change="action.onContentPageSizeChange"
            />
          </div>
        </t-tab-panel>

        <t-tab-panel value="modelView" label="数字人视图">
          <div v-if="state.models.length > 0"
               class="model-view">
            <div
              v-for="model in state.models"
              :key="model.id"
              class="model-card"
            >
              <div class="model-details">
                <video class="model-image" :src="getModelThumbnail(model)"/>
                <div class="model-name">{{ model.name }}</div>
              </div>

              <div class="model-assignments">
                <div class="assignments-header">
                  <div class="assignments-title">分配的内容</div>
                  <div class="assignments-count">{{ getModelAssignmentCount(model.id) }}</div>
                </div>

                <div class="assignments-list">
                  <div
                    v-for="contentId in getContentIdsForModel(model.id)"
                    :key="contentId"
                    class="assignment-item"
                  >
                    <div class="content-info">
                      <div class="content-name">{{ getContentName(contentId) }}</div>
                      <div class="content-type">
                        <span class="type-badge audio">音频</span>
                      </div>
                    </div>
                    <t-button
                      class="remove-btn"
                      theme="danger"
                      variant="text"
                      size="small"
                      @click="action.removeAssignment(contentId, model.id)"
                    >
                      移除
                    </t-button>
                  </div>

                  <div class="assignment-selector">
                    <t-select
                      class="content-selector"
                      v-model="state.selectedContent[model.id]"
                      placeholder="选择内容"
                      clearable
                    >
                      <t-option
                        v-for="item in getUnassignedContentItems()"
                        :key="item.id"
                        :value="item.id"
                        :label="item.name || '未命名'"
                      >
                        <div class="content-option">
                          <span class="content-type-badge audio">音频</span>
                          <span class="content-name">{{ item.name || '未命名' }}</span>
                        </div>
                      </t-option>
                    </t-select>
                    <t-button
                      class="add-btn"
                      theme="primary"
                      size="small"
                      @click="action.addSelectedContent(model.id)"
                      :disabled="!state.selectedContent[model.id]"
                    >
                      添加
                    </t-button>
                  </div>
                </div>
              </div>
            </div>
          </div>
          <!-- 有内容无模型时显示 -->
          <div v-else-if="state.models.length === 0" class="no-models">
            <div class="loading-models">
              <t-loading :loading="state.loadingModels" />
              <div class="loading-text">{{ state.loadingModels ? '加载数字人中...' : '未找到数字人模型' }}</div>
            </div>
          </div>
          <!-- 添加分页控件 -->
          <div class="pagination-container" v-if="state.totalCount > 0">
            <t-pagination
              v-model="state.modelPagination.current"
              v-model:pageSize="state.modelPagination.pageSize"
              :total="state.totalCount"
              :page-size-options="[10, 20, 50, 100]"
              @change="action.onPageChange"
              @page-size-change="action.onPageSizeChange"
            />
          </div>
        </t-tab-panel>
      </t-tabs>
    </div>

    <!-- 添加数字人选择器模态窗口 -->
    <t-dialog
      v-model:visible="state.modelSelectorVisible"
      header="选择数字人"
      width="800px"
      :footer="false"
      class="model-selector-dialog"
    >
      <div class="model-selector-container">
        <!-- 搜索框 -->
        <div class="model-search">
          <t-input
            v-model="state.modalSearchTerm"
            placeholder="搜索数字人"
            clearable
            @enter="action.searchModalModels"
          />
          <t-button @click="action.searchModalModels">搜索</t-button>
        </div>

        <!-- 分类筛选，可折叠 -->
        <t-collapse v-if="modelSource === 'common'" v-model="state.expandedPanels">
          <t-collapse-panel value="categoryFilters" header="分类筛选" class="category-filters-panel">
            <div class="modal-category-filters">
              <div class="filter-row">
                <span class="filter-label">一级分类:</span>
                <t-select
                  v-model="state.modalFilters.primaryCategoryId"
                  placeholder="选择一级分类"
                  clearable
                  @change="action.onModalPrimaryCategoryChange"
                >
                  <t-option
                    v-for="category in state.categoryTree"
                    :key="category.id"
                    :value="category.id"
                    :label="category.name"
                  />
                </t-select>
              </div>

              <div class="filter-row">
                <span class="filter-label">二级分类:</span>
                <t-select
                  v-model="state.modalFilters.secondaryCategoryId"
                  placeholder="选择二级分类"
                  clearable
                  :disabled="!state.modalFilters.primaryCategoryId"
                  @change="action.onModalSecondaryCategoryChange"
                >
                  <t-option
                    v-for="category in state.modalSecondaryCategories"
                    :key="category.id"
                    :value="category.id"
                    :label="category.name"
                  />
                </t-select>
              </div>

              <div class="filter-row">
                <span class="filter-label">三级分类:</span>
                <t-select
                  v-model="state.modalFilters.tertiaryCategoryId"
                  placeholder="选择三级分类"
                  clearable
                  :disabled="!state.modalFilters.secondaryCategoryId"
                  @change="action.fetchModalModels"
                >
                  <t-option
                    v-for="category in state.modalTertiaryCategories"
                    :key="category.id"
                    :value="category.id"
                    :label="category.name"
                  />
                </t-select>
              </div>
            </div>
          </t-collapse-panel>
        </t-collapse>

        <!-- 模型网格列表 -->
        <div class="model-grid">
          <div
            v-for="model in state.modalModels"
            :key="model.id"
            class="model-card"
            :class="{ selected: model.id === state.tempSelectedModelId }"
            @click="action.selectModalModel(model.id)"
          >
            <video class="model-thumbnail" :src="getModelThumbnail(model)" :poster="model.image_path"/>
            <div class="model-info">
              <div class="model-name">{{ model.name }}</div>
              <div v-if="model.primaryCategoryName" class="model-category">
                {{ model.primaryCategoryName }} / {{ model.secondaryCategoryName || '' }}
              </div>
            </div>
          </div>
        </div>

        <!-- 模态窗口中的分页控件 -->
        <div class="modal-pagination-container" v-if="state.modalTotalCount > 0">
          <t-pagination
            v-model="state.modalPagination.current"
            v-model:pageSize="state.modalPagination.pageSize"
            :total="state.modalTotalCount"
            :page-size-options="[12, 24, 48, 96]"
            @change="action.onModalPageChange"
            @page-size-change="action.onModalPageSizeChange"
          />
        </div>

        <!-- 模态窗口的底部操作按钮 -->
        <div class="modal-footer">
          <t-button theme="default" @click="action.closeModelSelector">取消</t-button>
          <t-button theme="primary" @click="action.confirmModelSelection" :disabled="!state.tempSelectedModelId">
            确定
          </t-button>
        </div>
      </div>
    </t-dialog>

    <!-- 批量分配确认对话框 -->
    <t-dialog
      v-model:visible="state.batchConfirmVisible"
      header="确认批量分配"
      width="400px"
      :confirm-btn="{ content: '确认', theme: 'primary' }"
      :cancel-btn="{ content: '取消' }"
      @confirm="action.confirmBatchAssign"
    >
      <p>
        您确定要将{{ state.includeAssigned ? '所有' : '未分配的' }}内容项分配给 "{{ getSelectedModelName() }}" 吗？
      </p>
      <p v-if="state.includeAssigned && getTotalContent() > 0" style="color: #FF932F; margin-top: 8px;">
        将重新分配 {{ getTotalContent() }} 个内容项，包括已分配给其他数字人的内容。
      </p>
      <p v-else-if="getUnassignedContentItems().length === 0" style="color: #FF932F; margin-top: 8px;">
        当前没有未分配的内容项。请勾选"包含已分配的内容项"选项以重新分配所有内容。
      </p>
      <p v-else style="color: #FF932F; margin-top: 8px;">
        将分配 {{ getUnassignedContentItems().length }} 个未分配的内容项。
      </p>
    </t-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted, watch } from 'vue';
import { SearchIcon, InfoCircleIcon } from 'tdesign-icons-vue-next';
import { MessagePlugin } from 'tdesign-vue-next';
import { getCommonModelList, modelPage, getCategoryTree, getIP } from '@renderer/api'
import { getAssetPathByKey } from '@renderer/api/assetPaths'

const assetPaths = ref('')

const props = defineProps({
  modelValue: {
    type: Object,
    default: () => ({})
  },
  listener: {
    type: Object,
    default: () => ({})
  },
  // 添加modelSource属性
  modelSource: {
    type: String,
    default: 'common'
  }
});

const videoData = defineModel({});
const emit = defineEmits(['assignAvatar', 'switchSource', 'update:modelValue']);

const state = reactive({
  // 模型相关
  models: [], // 在本组件内部管理模型列表
  loadingModels: false,
  totalCount: 0, // 总模型数量

  // 筛选和分页
  searchTerm: '',

  modelPagination: {
    current: 1,
    pageSize: 12, // 默认每页10条
  },

  // 新增内容视图的分页状态
  contentPagination: {
    current: 1,
    pageSize: 12,
  },

  // 分类相关
  categoryTree: [], // 完整的分类树
  secondaryCategories: [], // 当前选中的一级分类下的二级分类
  tertiaryCategories: [], // 当前选中的二级分类下的三级分类

  filters: {
    primaryCategoryId: null,
    secondaryCategoryId: null,
    tertiaryCategoryId: null,
  },

  // UI状态
  activeTab: 'contentView',
  selectedContent: {}, // 存储每个模型选中的内容项
  batchSelectedModel: null, // 批量分配选中的模型
  batchConfirmVisible: false, // 批量分配确认对话框
  includeAssigned: false, // 是否包含已分配的内容项

  // 新增 - 数字人选择器模态窗口状态
  modelSelectorVisible: false,
  tempSelectedModelId: null, // 临时选中的模型ID
  targetContentId: null, // 目标内容ID（单项分配时使用）

  // 模态窗口的搜索、筛选和分页状态
  modalSearchTerm: '',
  modalFilters: {
    primaryCategoryId: null,
    secondaryCategoryId: null,
    tertiaryCategoryId: null,
  },
  modalSecondaryCategories: [],
  modalTertiaryCategories: [],
  modalModels: [],
  modalTotalCount: 0,
  modalPagination: {
    current: 1,
    pageSize: 12, // 网格布局默认显示12个
  },
  loadingModalModels: false,
  expandedPanels: [], // 折叠面板状态

  // 添加模型缓存，用于存储已选模型的详细信息
  selectedModelsCache: {},  // 格式: { modelId: modelObject }
});

// 获取当前页的内容项
const getCurrentPageContentItems = () => {
  const startIndex = (state.contentPagination.current - 1) * state.contentPagination.pageSize;
  const endIndex = startIndex + state.contentPagination.pageSize;
  return videoData.value.contentItems.slice(startIndex, endIndex);
};

// 计算属性：已分配的内容项数量
const assignedCount = computed(() => {
  return videoData.value.assignments.filter(a => a.modelId).length;
});

// 计算属性：内容项总数
const totalCount = computed(() => {
  return videoData.value.contentItems.length;
});

// 获取所有内容项数量
const getTotalContent = () => {
  return videoData.value.contentItems.length;
};

// 根据内容ID获取分配的模型ID
const getAssignedModelId = (contentId) => {
  const assignment = videoData.value.assignments.find(a => a.contentId === contentId);
  return assignment ? assignment.modelId : null;
};

// 根据内容ID获取分配的模型名称
const getAssignedModelName = (contentId) => {
  const modelId = getAssignedModelId(contentId);
  if (!modelId) return '';

  // 优先从缓存中查找
  if (state.selectedModelsCache[modelId]) {
    return state.selectedModelsCache[modelId].name;
  }

  // 其次从当前加载的模型列表中查找
  const model = state.models.find(m => m.id === modelId) ||
    state.modalModels.find(m => m.id === modelId);

  if (model) {
    // 找到后也添加到缓存
    state.selectedModelsCache[modelId] = model;
    return model.name;
  }

  return '未知模型';
};

// 获取选中的批量分配模型名称
const getSelectedModelName = () => {
  if (!state.batchSelectedModel) return '';

  // 优先从缓存中查找
  if (state.selectedModelsCache[state.batchSelectedModel]) {
    return state.selectedModelsCache[state.batchSelectedModel].name;
  }

  // 其次从当前加载的模型列表中查找
  const model = state.models.find(m => m.id === state.batchSelectedModel) ||
    state.modalModels.find(m => m.id === state.batchSelectedModel);

  if (model) {
    // 找到后也添加到缓存
    state.selectedModelsCache[state.batchSelectedModel] = model;
    return model.name;
  }

  return '未知模型';
};

// 获取模型缩略图
const getModelThumbnail = (model) => {
  return model.video_path || '#';
};

// 获取分配给指定模型的内容项数量
const getModelAssignmentCount = (modelId) => {
  return videoData.value.assignments.filter(a => a.modelId === modelId).length;
};

// 获取分配给指定模型的内容项ID列表
const getContentIdsForModel = (modelId) => {
  return videoData.value.assignments
    .filter(a => a.modelId === modelId)
    .map(a => a.contentId);
};

// 根据内容ID获取内容名称
const getContentName = (contentId) => {
  const contentItem = videoData.value.contentItems.find(item => item.id === contentId);
  return contentItem ? (contentItem.name || '未命名') : '未知内容';
};

// 获取未分配的内容项列表
const getUnassignedContentItems = () => {
  // 获取所有已分配了模型的内容ID
  const assignedContentIds = videoData.value.assignments
    .filter(a => a.modelId) // 只考虑已分配的内容
    .map(a => a.contentId);

  // 返回未分配的内容项
  return videoData.value.contentItems.filter(item => !assignedContentIds.includes(item.id));
};

// 初始化加载分类数据
onMounted(async () => {
  await getAssetPathByKey('model').then(result => {
    assetPaths.value = result.path_value;
  })

  if (props.modelSource === 'common') {
    await action.loadCategoryTree();
  }
  await action.fetchModels();
});

watch(() => props.modelSource, async (newSource) => {
  // Reset filters when switching sources
  if (newSource === 'local') {
    state.filters.primaryCategoryId = null;
    state.filters.secondaryCategoryId = null;
    state.filters.tertiaryCategoryId = null;
    state.modalFilters.primaryCategoryId = null;
    state.modalFilters.secondaryCategoryId = null;
    state.modalFilters.tertiaryCategoryId = null;
  }
  // Reset modelPagination
  state.modelPagination.current = 1;
  // Fetch models for the new source
  await action.fetchModels();
}, { immediate: false });

const action = {
  // 新增内容视图的分页事件处理
  onContentPageChange(pageInfo) {
    state.contentPagination.current = pageInfo.current;
  },

  onContentPageSizeChange(pageSize) {
    state.contentPagination.pageSize = pageSize;
    state.contentPagination.current = 1; // 重置到第一页
  },

  // 切换模型源
  switchModelSource(source) {
    state.batchSelectedModel = null;
    if (props.modelSource !== source) {
      // 如果有已分配的模型，显示确认对话框
      if (assignedCount.value > 0) {
        if (confirm('切换模型库将清空所有已分配的模型，确定要继续吗？')) {
          // 通知父组件切换模型源
          emit('switchSource', source);
        }
      } else {
        // 没有已分配的模型，直接切换
        emit('switchSource', source);
      }
    }
  },

  // 加载分类树
  async loadCategoryTree() {
    try {
      state.loadingModels = true;
      const result = await getCategoryTree();

      if (result && result.data) {
        state.categoryTree = result.data;
      } else {
        console.error('加载分类树失败:', result.message);
        MessagePlugin.error('加载分类数据失败: ' + result.message);
        state.categoryTree = [];
      }
    } catch (error) {
      console.error('加载分类树失败', error);
      MessagePlugin.error('加载分类数据失败: ' + error.message);
      state.categoryTree = [];
    } finally {
      state.loadingModels = false;
    }
  },
  // 一级分类变更
  onPrimaryCategoryChange() {
    // 重置二级和三级分类
    state.filters.secondaryCategoryId = null;
    state.filters.tertiaryCategoryId = null;
    state.tertiaryCategories = [];

    // 查找选中的一级分类
    if (state.filters.primaryCategoryId) {
      const primaryCategory = state.categoryTree.find(
        category => category.id === state.filters.primaryCategoryId
      );

      // 设置二级分类列表
      state.secondaryCategories = primaryCategory?.children || [];
    } else {
      state.secondaryCategories = [];
    }

    // 重新获取模型列表
    action.fetchModels();
  },

  // 二级分类变更
  onSecondaryCategoryChange() {
    // 重置三级分类
    state.filters.tertiaryCategoryId = null;

    // 查找选中的二级分类
    if (state.filters.secondaryCategoryId) {
      const primaryCategory = state.categoryTree.find(
        category => category.id === state.filters.primaryCategoryId
      );

      const secondaryCategory = primaryCategory?.children.find(
        category => category.id === state.filters.secondaryCategoryId
      );

      // 设置三级分类列表
      state.tertiaryCategories = secondaryCategory?.children || [];
    } else {
      state.tertiaryCategories = [];
    }

    // 重新获取模型列表
    action.fetchModels();
  },
  // 页码变更
  async onPageChange(pageInfo) {
    state.modelPagination.current = pageInfo.current;
    await action.fetchModels();
  },

  // 每页数量变更
  async onPageSizeChange(pageSize) {
    state.modelPagination.pageSize = pageSize;
    state.modelPagination.current = 1;
    await action.fetchModels();
  },

  // 根据当前条件获取模型数据
  async fetchModels() {
    state.loadingModels = true;

    try {
      if (props.modelSource === 'common') {
        await action.fetchCommonModels();
      } else {
        await action.fetchLocalModels();
      }
    } catch (error) {
      console.error('获取模型数据失败', error);
      MessagePlugin.error('获取模型数据失败: ' + error.message);
      state.models = [];
      state.totalCount = 0;
    } finally {
      state.loadingModels = false;
    }
  },

  // 获取公共库模型
  async fetchCommonModels() {
    const params = {
      page: state.modelPagination.current,
      pageSize: state.modelPagination.pageSize,
      name: state.searchTerm || undefined,
      primaryCategoryId: state.filters.primaryCategoryId || undefined,
      secondaryCategoryId: state.filters.secondaryCategoryId || undefined,
      tertiaryCategoryId: state.filters.tertiaryCategoryId || undefined
    };

    const result = await getCommonModelList(params);
    if (result && result.data) {
      // 格式化模型数据
      state.models = result.data.records.map(model => ({
        id: model.id,
        name: model.name,
        video_path: `${assetPaths.value}/${model.videoPath}`,
        audio_Path: `${assetPaths.value}/${model.audioPath.replace("\\","/")}`,
        image_path: `${assetPaths.value}/${model.imagePath}`,
        voice_id: model.voiceId,
        isCommonModel: true,
        primaryCategoryId: model.primaryCategoryId,
        secondaryCategoryId: model.secondaryCategoryId,
        tertiaryCategoryId: model.tertiaryCategoryId,
        primaryCategoryName: model.primaryCategoryName,
        secondaryCategoryName: model.secondaryCategoryName,
        tertiaryCategoryName: model.tertiaryCategoryName,
      }));

      state.totalCount = result.data.total || 0;
    } else {
      state.models = [];
      state.totalCount = 0;
    }
  },
  // 获取本地模型
  async fetchLocalModels() {
    const params = {
      page: state.modelPagination.current,
      pageSize: state.modelPagination.pageSize,
      name: state.searchTerm || undefined
    };

    const result = await modelPage(params);

    if (result && result.list) {
      state.models = result.list;
      state.totalCount = result.total || 0;
    } else {
      state.models = [];
      state.totalCount = 0;
    }
  },

  // 搜索模型
  async searchModels() {
    state.modelPagination.current = 1; // 重置到第一页
    await action.fetchModels();
  },

  // 为内容项分配数字人模型
  assignModel(contentId, modelId) {
    // Query if the content item already has an assignment
    const assignmentIndex = videoData.value.assignments.findIndex(
      a => a.contentId === contentId
    );

    if (assignmentIndex !== -1) {
      // Update existing assignment
      videoData.value.assignments[assignmentIndex].modelId = modelId;
    } else {
      // Create new assignment
      videoData.value.assignments.push({
        contentId,
        modelId
      });
    }

    emit('assignAvatar', contentId, modelId);
  },

  // 预览音频内容
  previewAudio(item) {
    if (item.audioUrl) {
      props.listener.listen({
        name: item.name || '未命名',
        audioUrl: item.audioUrl
      });
    } else {
      MessagePlugin.warning('音频文件不可用');
    }
  },

  // 移除内容项与数字人的分配关系
  removeAssignment(contentId, modelId) {
    const assignmentIndex = videoData.value.assignments.findIndex(
      a => a.contentId === contentId && a.modelId === modelId
    );

    if (assignmentIndex !== -1) {
      // Set modelId to null to indicate unassigned
      videoData.value.assignments[assignmentIndex].modelId = null;
      emit('assignAvatar', contentId, null);
      MessagePlugin.success('已移除分配'); // Keep this single notification as it's a user-initiated action
    }
  },

  // 添加选中的内容项到数字人
  addSelectedContent(modelId) {
    const contentId = state.selectedContent[modelId];
    if (contentId) {
      action.assignModel(contentId, modelId);
      state.selectedContent[modelId] = null; // Clear selection
      MessagePlugin.success('添加成功'); // Keep this single notification as it's a user-initiated action
    }
  },

  // 打开数字人选择器模态窗口
  openModelSelectorModal(event, contentId = null) {
    // 重置模态窗口状态
    state.modalSearchTerm = '';
    state.modalPagination.current = 1;

    // 如果是为单个内容项选择模型，记录目标内容ID
    state.targetContentId = contentId;

    // 如果是批量分配或已有选定的模型，预选中该模型
    if (!contentId && state.batchSelectedModel) {
      state.tempSelectedModelId = state.batchSelectedModel;
    } else if (contentId) {
      // 如果是为单个内容项选择，预选中已分配的模型
      state.tempSelectedModelId = getAssignedModelId(contentId);
    } else {
      state.tempSelectedModelId = null;
    }

    // 加载当前分类筛选状态到模态窗口
    if (props.modelSource === 'common') {
      state.modalFilters.primaryCategoryId = state.filters.primaryCategoryId;
      state.modalFilters.secondaryCategoryId = state.filters.secondaryCategoryId;
      state.modalFilters.tertiaryCategoryId = state.filters.tertiaryCategoryId;
      state.modalSecondaryCategories = state.secondaryCategories;
      state.modalTertiaryCategories = state.tertiaryCategories;
    }

    // 获取模态窗口的模型数据
    action.fetchModalModels();

    // 显示模态窗口
    state.modelSelectorVisible = true;
  },

  // 关闭数字人选择器模态窗口
  closeModelSelector() {
    state.modelSelectorVisible = false;
    state.tempSelectedModelId = null;
    state.targetContentId = null;
  },

  // 在模态窗口中选择模型
  selectModalModel(modelId) {
    state.tempSelectedModelId = modelId;

    // 找到该模型并加入缓存
    const selectedModel = state.modalModels.find(m => m.id === modelId);
    if (selectedModel) {
      state.selectedModelsCache[modelId] = selectedModel;
    }
  },

  // 确认模型选择
  confirmModelSelection() {
    if (!state.tempSelectedModelId) return;

    if (state.targetContentId) {
      // Assign model to a single content item
      action.assignModel(state.targetContentId, state.tempSelectedModelId);
      // Add a single success message for this specific action
      MessagePlugin.success('分配成功');
    } else {
      // Batch assignment mode - just set the selected model, don't show message yet
      state.batchSelectedModel = state.tempSelectedModelId;
    }

    // Close the modal window
    action.closeModelSelector();
  },

  // 清除已选模型
  clearSelectedModel() {
    state.batchSelectedModel = null;
  },

  // 模态窗口的分页事件处理
  onModalPageChange(pageInfo) {
    state.modalPagination.current = pageInfo.current;
    action.fetchModalModels();
  },

  onModalPageSizeChange(pageSize) {
    state.modalPagination.pageSize = pageSize;
    state.modalPagination.current = 1;
    action.fetchModalModels();
  },

  // 模态窗口中的搜索处理
  searchModalModels() {
    state.modalPagination.current = 1;
    action.fetchModalModels();
  },

  // 模态窗口中的一级分类变更
  onModalPrimaryCategoryChange() {
    // 重置二级和三级分类
    state.modalFilters.secondaryCategoryId = null;
    state.modalFilters.tertiaryCategoryId = null;
    state.modalTertiaryCategories = [];

    // 查找选中的一级分类
    if (state.modalFilters.primaryCategoryId) {
      const primaryCategory = state.categoryTree.find(
        category => category.id === state.modalFilters.primaryCategoryId
      );

      // 设置二级分类列表
      state.modalSecondaryCategories = primaryCategory?.children || [];
    } else {
      state.modalSecondaryCategories = [];
    }

    // 重新获取模型列表
    action.fetchModalModels();
  },

  // 模态窗口中的二级分类变更
  onModalSecondaryCategoryChange() {
    // 重置三级分类
    state.modalFilters.tertiaryCategoryId = null;

    // 查找选中的二级分类
    if (state.modalFilters.secondaryCategoryId) {
      const primaryCategory = state.categoryTree.find(
        category => category.id === state.modalFilters.primaryCategoryId
      );

      const secondaryCategory = primaryCategory?.children.find(
        category => category.id === state.modalFilters.secondaryCategoryId
      );

      // 设置三级分类列表
      state.modalTertiaryCategories = secondaryCategory?.children || [];
    } else {
      state.modalTertiaryCategories = [];
    }

    // 重新获取模型列表
    action.fetchModalModels();
  },

  // 获取模态窗口的模型数据
  async fetchModalModels() {
    state.loadingModalModels = true;

    try {
      if (props.modelSource === 'common') {
        await action.fetchModalCommonModels();
      } else {
        await action.fetchModalLocalModels();
      }
    } catch (error) {
      console.error('获取模态窗口模型数据失败', error);
      MessagePlugin.error('获取模型数据失败: ' + error.message);
      state.modalModels = [];
      state.modalTotalCount = 0;
    } finally {
      state.loadingModalModels = false;
    }
  },

  // 获取模态窗口的公共库模型
  async fetchModalCommonModels() {
    const params = {
      page: state.modalPagination.current,
      pageSize: state.modalPagination.pageSize,
      name: state.modalSearchTerm || undefined,
      primaryCategoryId: state.modalFilters.primaryCategoryId || undefined,
      secondaryCategoryId: state.modalFilters.secondaryCategoryId || undefined,
      tertiaryCategoryId: state.modalFilters.tertiaryCategoryId || undefined
    };

    const result = await getCommonModelList(params);

    if (result && result.data) {
      // 格式化模型数据
      state.modalModels = result.data.records.map(model => {
        const formattedModel = {
          id: model.id,
            name: model.name,
          video_path: `${assetPaths.value}/${model.videoPath}`,
          audio_Path: `${assetPaths.value}/${model.audioPath.replace("\\","/")}`,
          image_path: `${assetPaths.value}/${model.imagePath}`,
          voice_id: model.voiceId,
          isCommonModel: true,
          primaryCategoryId: model.primaryCategoryId,
          secondaryCategoryId: model.secondaryCategoryId,
          tertiaryCategoryId: model.tertiaryCategoryId,
          primaryCategoryName: model.primaryCategoryName,
          secondaryCategoryName: model.secondaryCategoryName,
          tertiaryCategoryName: model.tertiaryCategoryName,
      };

      // 添加到缓存
      state.selectedModelsCache[model.id] = formattedModel;

      return formattedModel;
    });

      state.modalTotalCount = result.data.total || 0;
    } else {
      state.modalModels = [];
      state.modalTotalCount = 0;
    }
  },

  // 获取模态窗口的本地模型
  async fetchModalLocalModels() {
    const params = {
      page: state.modalPagination.current,
      pageSize: state.modalPagination.pageSize,
      name: state.modalSearchTerm || undefined
    };

    const result = await modelPage(params);

    if (result && result.list) {
      state.modalModels = result.list;

      // 将当前页面所有模型添加到缓存中
      result.list.forEach(model => {
        state.selectedModelsCache[model.id] = model;
      });

      state.modalTotalCount = result.total || 0;
    } else {
      state.modalModels = [];
      state.modalTotalCount = 0;
    }
  },

  // 打开批量分配确认对话框
  batchAssignModel() {
    if (!state.batchSelectedModel) {
      MessagePlugin.warning('请先选择要批量分配的数字人');
      return;
    }

    // 如果没有未分配的内容项且不包含已分配的，提示用户
    if (!state.includeAssigned && getUnassignedContentItems().length === 0) {
      MessagePlugin.warning('没有未分配的内容项，可勾选"包含已分配的内容项"选项进行重新分配');
      return;
    }

    state.batchConfirmVisible = true;
  },

  // 确认执行批量分配
  confirmBatchAssign() {
    // Determine which content items to assign
    let itemsToAssign = [];

    if (state.includeAssigned) {
      // Include all content items
      itemsToAssign = videoData.value.contentItems;
    } else {
      // Only include unassigned items
      itemsToAssign = getUnassignedContentItems();
    }

    if (itemsToAssign.length === 0) {
      MessagePlugin.info('没有可分配的内容项');
      state.batchConfirmVisible = false;
      return;
    }

    // Assign the selected model to all chosen content items
    // Don't display individual success messages for each assignment
    itemsToAssign.forEach(item => {
      // Call assignModel without triggering individual success messages
      action.assignModel(item.id, state.batchSelectedModel);
    });

    // Show only one success message after all assignments are complete
    MessagePlugin.success(`已成功将 ${itemsToAssign.length} 个内容项分配给 "${getSelectedModelName()}"`);
    state.batchConfirmVisible = false;
  },
};
</script>

<style lang="less" scoped>
.loading-content {
  color: rgba(0, 0, 0, 0.6);
  font-size: 16px;
  text-align: center;

  .loading-text {
    margin-top: 12px;
  }
}

:deep(.t-input__inner) {
  color: black;
}

/* 添加模型源选择器样式 */
.model-source-selector {
  display: flex;
  margin: 0 0 16px;
  background-color: #f5f5f5;
  border-radius: 4px;
  padding: 4px;

  .selector-option {
    flex: 1;
    text-align: center;
    padding: 8px 0;
    font-size: 13px;
    color: rgba(0, 0, 0, 0.7);
    cursor: pointer;
    border-radius: 3px;
    transition: all 0.2s ease;

    &:hover {
      color: rgba(0, 0, 0, 0.9);
    }

    &.active {
      background-color: #ffffff;
      color: #0052d9;
      box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
    }
  }
}

.assignment {
  display: flex;
  flex-direction: column;
  height: 100%;
  background-color: #ffffff; // 改为白色背景
  color: #333333; // 文字改为深色
  padding: 16px;

  &-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 16px;

    .title {
      font-weight: 500;
      font-size: 16px;
      color: #333333;
    }

    .stats {
      font-size: 14px;
      color: rgba(0, 0, 0, 0.6);
    }
  }

  /* 批量分配区域 - 更新为按钮样式 */
  .batch-assignment {
    background: #f5f5f5;
    border-radius: 4px;
    border: 1px solid #e0e0e0;
    padding: 16px;
    margin-bottom: 16px;

    &-title {
      font-weight: 500;
      font-size: 14px;
      color: #333333;
      margin-bottom: 12px;
    }

    &-control {
      display: flex;
      gap: 12px;
      margin-bottom: 12px;

      /* 新增：模型选择器按钮容器 */
      .model-selector-button-container {
        flex: 1;
        display: flex;
        align-items: center;
        gap: 8px;
      }

      /* 新增：模型选择器按钮 */
      .model-selector-button {
        flex: 1;
        text-align: left;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        background-color: #ffffff;
        border: 1px solid #e0e0e0;
        color: #333333;
        padding: 0 12px;
        height: 32px;
        border-radius: 3px;
        font-size: 14px;
        display: flex;
        align-items: center;

        &:hover {
          background-color: #f9f9f9;
          border-color: #d0d0d0;
        }
      }
    }

    /* 批量分配选项 */
    .batch-options {
      display: flex;
      align-items: center;
      color: rgba(0, 0, 0, 0.8);

      :deep(.t-checkbox) {
        --td-checkbox-color: rgba(0, 0, 0, 0.8);
      }

      .info-icon {
        margin-left: 8px;
        color: rgba(0, 0, 0, 0.6);
        cursor: pointer;
      }
    }
  }

  &-search {
    margin-bottom: 16px;

    .search-input {
      --td-bg-color-specialcomponent: #ffffff;
      --td-text-color-primary: #333333;
      --td-text-color-placeholder: rgba(0, 0, 0, 0.4);

      :deep(.t-input) {
        border-color: #e0e0e0;
        background-color: #ffffff;
        color: #333333;
      }

      :deep(.t-input--focused) {
        box-shadow: none;
      }

      :deep(.t-input__prefix-icon) {
        color: #666666;
      }
    }
  }

  .no-content, .no-models {
    flex: 1;
    display: flex;
    justify-content: center;
    align-items: center;

    .empty-message, .loading-models {
      color: rgba(0, 0, 0, 0.6);
      font-size: 16px;
      text-align: center;
      margin-top: 350px;
      .loading-text {
        margin-top: 12px;
      }
    }
  }

  &-tabs {
    flex: 1;
    background-color: #ffffff;

    :deep(.t-tabs__header) {
      border-bottom-color: #e0e0e0;
      background-color: #ffffff;
    }

    :deep(.t-tabs__nav) {
      border-bottom-color: #e0e0e0;
      background-color: #ffffff;
    }

    :deep(.t-tabs__nav-item) {
      color: rgba(0, 0, 0, 0.6);
      background-color: #ffffff;

      &.t-is-active {
        color: #0052d9;
      }
    }

    :deep(.t-tabs__content) {
      height: calc(100% - 48px);
      overflow: auto;
      background-color: #ffffff;
    }

    :deep(.t-tabs__panel) {
      background-color: #ffffff;
    }
  }

  .content-view {
    display: flex;
    flex-direction: column;
    gap: 16px;
    padding: 16px 0;
    background-color: #ffffff;

    .content-item {
      background: #fafafa;
      border-radius: 4px;
      border: 1px solid #e0e0e0;
      padding: 16px;
      display: flex;
      flex-direction: column;
      gap: 12px;

      .content-details {
        display: flex;
        flex-direction: column;
        gap: 8px;

        .content-type {
          .type-badge {
            display: inline-block;
            padding: 2px 8px;
            border-radius: 2px;
            font-size: 12px;
            font-weight: 500;

            &.text {
              background: rgba(48, 156, 255, 0.1);
              color: #309CFF;
            }

            &.audio {
              background: rgba(255, 147, 47, 0.12);
              color: #FF932F;
            }
          }
        }

        .content-name {
          font-weight: 500;
          font-size: 14px;
          color: #333333;
        }

        .content-preview {
          font-size: 12px;
          color: rgba(0, 0, 0, 0.6);

          .text-preview {
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
          }

          .audio-preview {
            display: flex;
            align-items: center;
            justify-content: space-between;

            .preview-btn {
              min-width: 48px;
              height: 24px;
              border-radius: 2px;
              font-size: 12px;
            }
          }
        }
      }

      .content-assignment {
        display: flex;
        align-items: center;
        gap: 8px;

        .assignment-label {
          font-size: 14px;
          color: #333333;
          white-space: nowrap;
        }

        /* 更新：单个内容的模型选择器 */
        .single-model-selector {
          flex: 1;
          display: flex;
          align-items: center;
          gap: 8px;

          .model-selector-button {
            flex: 1;
            text-align: left;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
            background-color: #ffffff;
            border: 1px solid #e0e0e0;
            color: #333333;
            padding: 0 12px;
            height: 32px;
            border-radius: 3px;
            font-size: 14px;
            display: flex;
            align-items: center;

            &:hover {
              background-color: #f9f9f9;
              border-color: #d0d0d0;
            }
          }
        }

        .model-option {
          display: flex;
          align-items: center;
          gap: 8px;

          .model-thumbnail {
            width: 24px;
            height: 24px;
            border-radius: 2px;
            object-fit: cover;
          }

          .model-name {
            color: #333333;
          }
        }
      }
    }
  }

  .model-view {
    display: flex;
    flex-direction: column;
    gap: 24px;
    padding: 16px 0;
    background-color: #ffffff;

    .model-card {
      background: #fafafa;
      border-radius: 4px;
      border: 1px solid #e0e0e0;
      overflow: hidden;

      .model-details {
        padding: 16px;
        display: flex;
        align-items: center;
        gap: 12px;
        border-bottom: 1px solid #e0e0e0;

        .model-image {
          width: 64px;
          border-radius: 4px;
          object-fit: cover;
          background-color: #f0f0f0;
        }

        .model-name {
          font-weight: 500;
          font-size: 16px;
          color: #333333;
        }
      }

      .model-assignments {
        padding: 16px;

        .assignments-header {
          display: flex;
          justify-content: space-between;
          align-items: center;
          margin-bottom: 12px;

          .assignments-title {
            font-weight: 500;
            font-size: 14px;
            color: #333333;
          }

          .assignments-count {
            font-size: 12px;
            color: rgba(0, 0, 0, 0.6);
          }
        }

        .assignments-list {
          display: flex;
          flex-direction: column;
          gap: 8px;

          .assignment-item {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 8px 12px;
            background: #f0f0f0;
            border-radius: 4px;

            .content-info {
              display: flex;
              align-items: center;
              gap: 8px;

              .content-name {
                font-size: 14px;
                color: #333333;
              }

              .content-type {
                .type-badge {
                  display: inline-block;
                  padding: 2px 8px;
                  border-radius: 2px;
                  font-size: 12px;
                  font-weight: 500;

                  &.text {
                    background: rgba(48, 156, 255, 0.1);
                    color: #309CFF;
                  }

                  &.audio {
                    background: rgba(255, 147, 47, 0.12);
                    color: #FF932F;
                  }
                }
              }
            }
          }

          .assignment-selector {
            display: flex;
            gap: 8px;
            margin-top: 12px;

            .content-selector {
              flex: 1;
              --td-bg-color-specialcomponent: #ffffff;
              --td-text-color-primary: #333333;
              --td-text-color-placeholder: rgba(0, 0, 0, 0.4);

              :deep(.t-select__input) {
                background-color: #ffffff;
                border-color: #e0e0e0;
                color: #333333;
              }

              :deep(.t-popup) {
                background-color: #ffffff;
                border-color: #e0e0e0;
              }
            }

            .content-option {
              display: flex;
              align-items: center;
              gap: 8px;

              .content-type-badge {
                display: inline-block;
                padding: 2px 4px;
                border-radius: 2px;
                font-size: 12px;

                &.text {
                  background: rgba(48, 156, 255, 0.1);
                  color: #309CFF;
                }

                &.audio {
                  background: rgba(255, 147, 47, 0.12);
                  color: #FF932F;
                }
              }

              .content-name {
                color: #333333;
              }
            }
          }
        }
      }
    }
  }
}

/* 确认对话框样式 */
:deep(.t-dialog) {
  background-color: #ffffff;

  .t-dialog__header {
    color: #333333;
    background-color: #ffffff;
  }

  .t-dialog__body {
    color: #333333;
    background-color: #ffffff;
  }

  .t-dialog__footer {
    background-color: #ffffff;
  }
}

/* 工具提示样式 */
:deep(.t-tooltip) {
  .t-tooltip__content {
    background-color: #333333;
    color: #ffffff;
  }
}

/* 添加分类筛选样式 */
.category-filters {
  background: #f5f5f5;
  border-radius: 4px;
  border: 1px solid #e0e0e0;
  padding: 16px;
  margin-bottom: 16px;
  display: flex;
  flex-direction: column;
  gap: 12px;

  .filter-row {
    display: flex;
    align-items: center;
    gap: 12px;

    .filter-label {
      width: 80px;
      font-size: 14px;
      color: #333333;
      white-space: nowrap;
    }

    :deep(.t-select) {
      flex: 1;
      --td-bg-color-specialcomponent: #ffffff;
      --td-text-color-primary: #333333;
      --td-text-color-placeholder: rgba(0, 0, 0, 0.4);

      .t-select__input {
        background-color: #ffffff;
        border-color: #e0e0e0;
        color: #333333;
      }
    }
  }
}

.pagination-container {
  margin-top: 20px;
  display: flex;
  justify-content: center;
  background: #f5f5f5;
  padding: 16px;
  border-radius: 4px;

  :deep(.t-pagination) {
    --td-bg-color-component: #ffffff;
    --td-text-color-primary: #333333;
    --td-bg-color-container: #ffffff;
    --td-text-color-secondary: rgba(0, 0, 0, 0.6);
    --td-brand-color: #0052d9;

    .t-button {
      background-color: #ffffff;
      border-color: #e0e0e0;

      &:hover {
        background-color: #f5f5f5;
      }

      &.t-is-active {
        background-color: var(--td-brand-color);
        color: #fff;
      }
    }

    .t-select {
      background-color: #ffffff;
      border-color: #e0e0e0;
      color: #333333;
    }
  }
}

:deep(.t-input.t-is-readonly) {
  color: var(--td-text-color-primary);
  background-color: #f5f5f5;
  width: auto;
}

/* 新增：数字人选择器模态窗口样式 */
.model-selector-dialog {
  :deep(.t-dialog__header) {
    border-bottom: 1px solid #e0e0e0;
  }

  :deep(.t-dialog__body) {
    padding: 16px;
  }
}

/* 新增：模型选择器容器 */
.model-selector-container {
  display: flex;
  flex-direction: column;
  gap: 16px;

  /* 搜索框 */
  .model-search {
    display: flex;
    gap: 12px;

    :deep(.t-input) {
      flex: 1;
      background-color: #ffffff;
      border-color: #e0e0e0;
      color: #333333;
    }
  }

  /* 折叠面板 */
  :deep(.t-collapse) {
    background: #ffffff;
    border: none;

    .t-collapse-panel {
      border: 1px solid #e0e0e0;
      border-radius: 4px;
      margin-bottom: 0;

      .t-collapse-panel__header {
        background: #f5f5f5;
        color: #333333;
      }

      .t-collapse-panel__content {
        background: #f5f5f5;
        padding: 16px;
      }
    }
  }

  /* 模态窗口中的分类筛选 */
  .modal-category-filters {
    display: flex;
    flex-direction: column;
    gap: 12px;

    .filter-row {
      display: flex;
      align-items: center;
      gap: 12px;

      .filter-label {
        width: 80px;
        font-size: 14px;
        color: #333333;
        white-space: nowrap;
      }

      :deep(.t-select) {
        flex: 1;
        --td-bg-color-specialcomponent: #ffffff;
        --td-text-color-primary: #333333;
        --td-text-color-placeholder: rgba(0, 0, 0, 0.4);

        .t-select__input {
          background-color: #ffffff;
          border-color: #e0e0e0;
          color: #333333;
        }
      }
    }
  }

  /* 模型网格 */
  .model-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 16px;

    .model-card {
      display: flex;
      flex-direction: column;
      background: #ffffff;
      border-radius: 4px;
      border: 1px solid #e0e0e0;
      padding: 12px;
      cursor: pointer;
      transition: all 0.2s;

      &:hover {
        background-color: #f9f9f9;
        border-color: #d0d0d0;
      }

      &.selected {
        border-color: #0052d9;
        background-color: rgba(0, 82, 217, 0.1);
      }

      .model-thumbnail {
        width: 100%;
        height: 100px;
        object-fit: cover;
        border-radius: 4px;
        background-color: #f0f0f0;
        margin-bottom: 8px;
      }

      .model-info {
        text-align: center;

        .model-name {
          font-weight: 500;
          font-size: 14px;
          color: #333333;
          margin-bottom: 4px;
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
        }

        .model-category {
          font-size: 12px;
          color: rgba(0, 0, 0, 0.6);
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
        }
      }
    }
  }

  /* 模态窗口的分页 */
  .modal-pagination-container {
    display: flex;
    justify-content: center;
    padding: 16px 0;
    border-top: 1px solid #e0e0e0;
    margin-top: 16px;

    :deep(.t-pagination) {
      --td-bg-color-component: #ffffff;
      --td-text-color-primary: #333333;
      --td-bg-color-container: #ffffff;
      --td-text-color-secondary: rgba(0, 0, 0, 0.6);
      --td-brand-color: #0052d9;

      .t-button {
        background-color: #ffffff;
        border-color: #e0e0e0;

        &:hover {
          background-color: #f5f5f5;
        }

        &.t-is-active {
          background-color: var(--td-brand-color);
          color: #fff;
        }
      }

      .t-select {
        background-color: #ffffff;
        border-color: #e0e0e0;
        color: #333333;
      }
    }
  }

  /* 模态窗口的底部 */
  .modal-footer {
    display: flex;
    justify-content: flex-end;
    gap: 12px;
    border-top: 1px solid #e0e0e0;
    padding-top: 16px;
    margin-top: 16px;
  }
}
</style>
